home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / OSLIB / README < prev    next >
Text File  |  1996-02-26  |  19KB  |  471 lines

  1. 12/09/95
  2. Introduction
  3. ============
  4.  
  5.    OSLib is a set of functions and C headers to provide complete
  6. coverage of the RISC O S application programmer's interface in C. It
  7. provides access from C code to all RISC O S system calls ("SWI's") which
  8. is
  9.  
  10.       efficient: often, memory access is completely avoided;
  11.       type-safe: every argument can be type-checked by the compiler;
  12.       obvious: a SWI is called by the "obvious" syntax;
  13.       complete: every SWI is covered;
  14.       register-safe: hides (often idiosyncratic) register allocation;
  15.       language-independent: although the headers are specific to C, the
  16.          library is not - any A P C S-conformant language can call it.
  17.  
  18. It also provides names for all the data structures and reason codes used
  19. by the A P I. Code that uses it is superior to similar code using
  20. _kernel_swi() or _swix(), both in terms of the compile-time checking
  21. that is available, and the size and speed of the code generated.
  22.  
  23.    In addition to the module files, there is also a file "types.h" which
  24. contains macros and types useful for any programme.
  25.  
  26.    This file explains how OSLib relates to the P R M descriptions of the
  27. SWI's in complete detail. It is best read in conjunction with the header
  28. files themselves.
  29.  
  30. The OSLib Structuring Conventions
  31. === ===== =========== ===========
  32.  
  33.    Each header file provides
  34.  
  35.       function prototypes
  36.       typedefs
  37.       macros
  38.  
  39. that completely specify the interface to a module. All symbols provided by
  40. "<module>.h" are of the form <module>_<name> (except some of the form
  41. <module><name>_<reason>). For functions, <name> is the name of the SWI,
  42. converted to lower-case, and with underscores inserted between each word:
  43.  
  44.       SWI                     Function
  45.       ---                     --------
  46.       OS_ReadLine             os_read_line
  47.       Wimp_CreateWindow       wimp_create_window
  48.  
  49. For typedefs, <name> is a sequence of words in lower-case, separated by
  50. underscores:
  51.  
  52.       Type                    Meaning
  53.       ----                    -------
  54.       os_colour               a palette entry value (0xbbggrr00)
  55.       wimp_window             a window definition structure
  56.  
  57. For macros, <name> is a sequence of words in upper-case, separated by
  58. underscores:
  59.  
  60.       Macro                   Meaning
  61.       -----                   -------
  62.       os_MODEVAR_XEIG_FACTOR  a value for os_read_mode_variable
  63.       error_ESCAPE            the error number of Escape (17)
  64.       wimp_ICON_NAME_LIMIT    the largest length of an icon name
  65.  
  66. (all macros for maximum values end in _LIMIT). There is also a special set
  67. of macros provided for more convenient handling of structures with a
  68. variable number of trailing parts, as used for mode selectors or Wimp
  69. window definitions, for example:
  70.  
  71.       Macro                   Meaning
  72.       -----                   -------
  73.       os_PALETTE (nc)         Declarator for a palette with |nc| colours
  74.       os_SIZEOF_PALETTE (nc)  Size of that palette
  75.       wimp_WINDOW (ni)        Declarator for a window with |ni| icons
  76.       wimp_SIZEOF_WINDOW (ni) Size of the complete window definition
  77.  
  78. Furthermore, every SWI number and SWI reason code has a macro defined of the
  79. form <Module>_<Name> (in mixed case form):
  80.  
  81.       Macro                   Value
  82.       -----                   -----
  83.       OS_WriteC               0
  84.       Font_FindFont           0x40081
  85.  
  86. These are rarely needed.
  87.  
  88.    In fact, for each SWI, two functions are provided: one has a name
  89. prefixed with an x and returns a value of type |os_error *|, which is non-
  90. null if the SWI fails; the other does not start with an x, and never returns
  91. an error: if the SWI fails, a signal (|SIGOSERROR|, number 10) is raised,
  92. and may be caught by installing a signal handler for it. The non-x form can
  93. therefore return a result, instead of having to write to an output argument:
  94. for example, the SWI Wimp_CreateWindow can be called by either of the
  95. prototypes
  96.  
  97.       os_error *xwimp_create_window (wimp_window *window, wimp_w *w);
  98.       wimp_w wimp_create_window (wimp_window *window);
  99.  
  100. They have exactly the same effect if all goes well, but if there is an
  101. error, the first just returns it, while the other raises |SIGOSERROR| and
  102. does not return at all. (If you use the second, the signal handler for
  103. |SIGOSERROR| can use _kernel_last_oserror() to find out what the error was.)
  104.  
  105.    The function prototype is derived from the SWI description in the
  106. following way. Arguments corresponding to input registers appear first in
  107. order in the argument list, followed by the addresses of variables in which
  108. the output registers' values are to be written. If an output register value
  109. is not needed, a null pointer can be written in that position. (Since |int|
  110. and all pointer types are 32 bits on the ARM, it doesn't matter which type
  111. of null pointer is used.)
  112.  
  113.    Most of the types are fully defined: e g, a |wimp_window| is a structure
  114. type with all the fields defined with the right type and name to be passed to
  115. any SWI that uses it. Some types are "abstract," however: they are exported
  116. by a module, but the internal structure is not accessible to its clients.
  117. The best way of representing this in C is by an unspecified pointer type: a
  118. definition of the form
  119.  
  120.       typedef struct <tag> *<type>
  121.  
  122. where the structure is never defined in full. Doing this allows the
  123. compiler to typecheck arguments of these types, as in the wimp_-
  124. create_window() example above.
  125.  
  126.    In addition, various modules use values from name spaces that are
  127. centrally allocated by Acorn. These include: |error_|, |message_|,
  128. |...v|, |event_| and |upcall_|, and they each have their own prefix.
  129. They correspond to error numbers, WIMP message numbers, vectors (which
  130. are reason codes for OS_CallAVector), service calls (reason codes for
  131. OS_ServiceCall), events (reason codes for OS_GenerateEvent) and upcalls
  132. (reason codes for OS_UpCall), respectively. In cases where name clashes
  133. are possible, the module name occurs in the <name> part:
  134.  
  135.       error_BUFFER_MANAGER_BUFFER_TOO_SMALL
  136.       error_COLOUR_TRANS_BAD_DEPTH
  137.  
  138. (Vectors are represented by a suffix, |...v|, rather than a prefix, since
  139. this is familiar.) These rules mean that if you are writing code for RISC
  140. O S, and you avoid
  141.  
  142.          (a) all names that start with the name <module> of any
  143.       "<module>.h" you need to include;
  144.  
  145.          (b) all names that start with |error|, |message|, |event|
  146.       or |upcall|, or end with |v|;
  147.  
  148. then no names clashes will occur.
  149.  
  150. Types.h
  151. =======
  152.  
  153.    All OSLib header files ensure that "types.h" is included. This file
  154. contains various types, macros for values, and function-like macros that
  155. are generally useful. There are further macros in "macros.h." They are
  156. described here:
  157.  
  158. Types
  159. -----
  160.  
  161.    |bits|: Used for flags values and masks, normally consisting of fields of
  162. 1 or more bits. Macros are normally provided to help with getting these
  163. fields out: for a 1-bit field, a macro |X| such that
  164.  
  165.       To                      Use
  166.       --                      ---
  167.       Read the field          (v & X) != NONE
  168.       Write a 0               v &= ~X
  169.       Write a 1               v |= X
  170.  
  171. and for a multi-bit field, macros X and X_SHIFT such that
  172.  
  173.       To                      Use
  174.       --                      ---
  175.       Read the field          (v & X) >> X_SHIFT
  176.       Write a value |w|       v = (v & ~X) | w << X_SHIFT.
  177.  
  178.    |bool|: Used for a truth value.
  179.  
  180.    |byte|: Used for a single byte value, as an alternative to |char| when the
  181. values are just data, rather than being characters as such. It is an unsigned
  182. type, which means that 2 instructions can be saved in P C C mode, where
  183. |char| is signed and must be sign-extended.
  184.  
  185. Constant-like macros
  186. ------------- ------
  187.  
  188.    |NULL|: the usual C null pointer constant.
  189.  
  190.    |FALSE|: value of type |bool| representing falsehood.
  191.  
  192.    |TRUE|: value of type |bool| representing truth.
  193.  
  194.    |NONE|: value of type |bits| with all bits clear.
  195.  
  196.    |ALL|: value of type |bits| with all bits set.
  197.  
  198.    |SKIP|: may be used as a "don't care" value for |int|, pointers,
  199. |bits|.
  200.  
  201.    |SIG_LIMIT|: largest signal number + 1.
  202.  
  203.    |_C|, |_Z|, |_N|, |_V|: masks for the flags in the P S R.
  204.  
  205.    |DEC_WIDTH|: the length of INT_MAX (2147483647) printed with %d.
  206.  
  207.    |SHORT_DEC_WIDTH|: the length of SHRT_MAX (32767) printed with %hd.
  208.  
  209.    |LONG_DEC_WIDTH|: the length of LONG_MAX (2147483647) printed with %ld.
  210.  
  211.    |OCT_WIDTH|: the length of UINT_MAX (37777777777) printed with %o.
  212.  
  213.    |SHORT_OCT_WIDTH|: the length of USHRT_MAX (177777) printed with %ho.
  214.  
  215.    |LONG_OCT_WIDTH|: the length of ULONG_MAX (37777777777) printed with %lo.
  216.  
  217.    |UNSIGNED_WIDTH|: the length of UINT_MAX (4294967295) printed with %u.
  218.  
  219.    |SHORT_UNSIGNED_WIDTH|: the length of USHRT_MAX (65535) printed with %hu.
  220.  
  221.    |LONG_UNSIGNED_WIDTH|: the length of ULONG_MAX (4294967295) printed with
  222. %lu.
  223.  
  224.    |HEX_WIDTH|: the length of UINT_MAX (FFFFFFFF) printed with %x.
  225.  
  226.    |SHORT_HEX_WIDTH|: the length of USHRT_MAX (FFFF) printed with %hx.
  227.  
  228.    |LONG_HEX_WIDTH|: the length of ULONG_MAX (FFFFFFFF) printed with %lx.
  229.  
  230.    |FLT_WIDTH|: the precision needed to distinguish 1 + FLT_EPSILON from 1
  231. printed with %f.
  232.  
  233.    |DBL_WIDTH|: the precision needed to distinguish 1 + DBL_EPSILON from 1
  234. printed with %f.
  235.  
  236.    |LDBL_WIDTH|: the precision needed to distinguish 1 + LDBL_EPSILON from 1
  237. printed with %Lf.
  238.  
  239.    |FLT_EXP_WIDTH|: the length of the exponent of FLT_MAX printed with %f.
  240.  
  241.    |DBL_EXP_WIDTH|: the length of the exponent of DBL_MAX printed with %f.
  242.  
  243.    |LDBL_EXP_WIDTH|: the length of the exponent of LDBL_MAX printed with %Lf.
  244.  
  245.    |ERROR|: intended as an "out-of-band" value to be returned by functions
  246. like fgetc() which return |EOF| on end-of-file. |ERROR| may be used to
  247. indicate an error condition.
  248.  
  249.    |UNKNOWN|: used to declare (but not define) arrays of unknown size, as
  250. an argument to the type macros (e g, wimp_WINDOW()) described above.
  251.  
  252. Function-like macros
  253. ------------- ------
  254.  
  255.    |WHETHER|: convert a bool value to a string.
  256.  
  257.    |MAX|: larger of two values.
  258.  
  259.    |MIN|: smaller of two values.
  260.  
  261.    |MAXAB|: larger of two values and assign.
  262.  
  263.    |MINAB|: smaller of two values and assign.
  264.  
  265.    |ABS|: absolute value.
  266.  
  267.    |SGN|: signum.
  268.  
  269.    |DIM|: positive difference.
  270.  
  271.    |SQR|: square.
  272.  
  273.    |RATIO|: integer division, rounding to nearer.
  274.  
  275.    |BOOL|: convert an integer to bool.
  276.  
  277.    |UCHAR|: character corresponding to a digit (upper case preferred).
  278.  
  279.    |LCHAR|: ditto, lower case.
  280.  
  281.    |BINEXP|: 2 to the power of.
  282.  
  283.    |ISDIGIT|: a digit?
  284.  
  285.    |ISXDIGIT|: a hex digit?
  286.  
  287.    |DIGIT|: if a digit, then which, else undefined.
  288.  
  289.    |XDIGIT|: if a hex digit, then which, else undefined.
  290.  
  291.    |DBLEQ|: equality for floating-point numbers (requires a tolerance)
  292.  
  293.    |BIT|: the bit at an offset from a pointer.
  294.  
  295.    |SET|: set a bit at an offset from a pointer.
  296.  
  297.    |CLR|: clear a bit at an offset from a pointer.
  298.  
  299.    |CLEAR|: clear a string.
  300.  
  301.    |EMPTY|: is a string empty?
  302.  
  303.    |NCOPY|: copy at most a given number of characters from a string, and
  304. terminate it.
  305.  
  306.    |STR_|: helper macro for STR.
  307.  
  308.    |STR|: convert a macro to source string.
  309.  
  310.    |COUNT|: number of elements in an array.
  311.  
  312.    |ALIGN|: round an integer up to the next multiple of 4.
  313.  
  314.    |WORD|: assembles an |int| from an unaligned byte pointer.
  315.  
  316.    |SHORT|: assembles a |short| from an unaligned byte pointer.
  317.  
  318. Macros that "change the language" 
  319. ------ ---- ------- --- ---------
  320.  
  321.    (Not everyone likes using these!) 
  322.  
  323.    |AS| is the same as |.|, but can be used to let the reader know that the
  324. left operand is a |union| rather than a |struct|.
  325.  
  326.    |ASREF| is the same as |->|, but can be used to let the reader know that
  327. the left operand is a |union *| rather than a |struct *|.
  328.  
  329.    |_| is the same as |,|, but if used to separate the arguments of a macro
  330. call is not recognised as a comma by the preprocessor. This lets you write
  331. macros with variable numbers of arguments.
  332.  
  333.    |__swi| is understood as a compiler directive by C release 5 (but not
  334. by earlier versions of C, nor by CFront) to call a function using a SWI
  335. instruction rather than by a BL. "Types.h" therefore includes some
  336. directives to enable the uses of |__swi| in the headers to be "hidden"
  337. in these cases by using -D__swi on the cc command line.
  338.  
  339. Macros to suppress compiler warnings
  340. ------ -- -------- -------- --------
  341.  
  342.    |NOT_USED|: Suppress "variable not used" message.
  343.  
  344.    |UNSET|: Suppress "variable may be used before being set" message.
  345.  
  346. Additional Structuring Rules 
  347. ========== =========== =====
  348.  
  349.    The design aims listed in paragraph 1 are not completely compatible. In
  350. order to provide type-safety, it is necessary to provide multiple veneers
  351. for some SWI's. These fall into two classes: where a SWI has multiple reason
  352. codes, each reason code is provided with a separate function; and where a
  353. SWI has two or more different variants, each variant is provided with its
  354. own function.
  355.  
  356. Reason codes 
  357. ------ -----
  358.  
  359.    Many SWI's have several reason codes each of which has its own distinct
  360. purpose and register usage. In this case, each reason code is provided with
  361. its own function. (SWI's with a "reason code" parameter which does not
  362. affect the interpretation of the other parameters are not treated like this:
  363. instead, the reason codes are just provided as macros.) In some cases, one
  364. reason code may itself have different sub-reason codes. In every case,
  365. the functions that are derived from the SWI use the entirety of the SWI
  366. name (with no underscore) as their prefix. Some have their own header
  367. file (e g, OS_SpriteOp, reason codes in "osspriteop.h"), others share
  368. the header file with the SWI (e g, PDriver_MiscOp, reason codes in
  369. "pdriver.h"). Toolbox_object_misc_op() has a dynamically extensible set
  370. of reason codes provided by object modules: these use the name of the
  371. object, and are in the object's header file.
  372.  
  373.    Where a header file name is longer than 10 characters, the full name
  374. should be used in |#include| statements. FileCore-based filing systems will
  375. truncate the file name to 10 characters, if the *Configure option 'Truncate'
  376. is 'On' (which is recommended). This means that, for example, the line
  377. |#include "messagetrans.h"| will work on all filing systems: FileCore-based
  378. ones will convert the name to "messagetra.h."
  379.  
  380.    OS_WriteI might be considered to have a reason code (the character to be
  381. written), but since it is part of the SWI number, each character has a
  382. separate function. This is not worthwhile for printing characters, but for
  383. other VDU codes gives useful calls like os_clg() (to clear the graphics
  384. window), os_bell() (to ring the bell) etc. (The complete list is
  385. in "os.h.")
  386.  
  387.    Many of the reason codes of OS_CallAVector have been omitted, namely,
  388. those where there are many sub-reason codes, and the purpose of the vector
  389. is exactly duplicated by a SWI or SWI's. So you will not find findv_-
  390. openin() (to call sub-reason code OSFind_OpenIn of reason code FindV of
  391. SWI OS_CallAVector), because it is identical in purpose to osfind_openin().
  392. If there are reason codes but no SWI, the reason codes do have functions
  393. provided (e g, PaletteV), and if there are no reason codes, the function is
  394. provided even if it does duplicate a SWI - for example, you can call
  395. os_writec() or wrchv() with the same effect (unless you are implementing
  396. them, of course). This is all just to keep the library size down: if it
  397. causes a problem, it can be reviewed. (Since calls to OS_GenerateEvent
  398. and OS_UpCall are already distributed through many files, vectored
  399. versions of them would have to be distributed in the same way.)
  400.  
  401.    Lastly, calls provided by FileSwitch are in "fileswitch.h", unless they
  402. have their own header. (The separate headers are "osargs.h," osfile.h,"
  403. osfind.h," osfscontrol.h," "osgbpb.h.") Also, some of the types that
  404. might be expected to be defined in these headers are actually defined in
  405. "fileswitch.h," to avoid circular references.
  406.  
  407. Variants
  408. --------
  409.  
  410.    Some SWI's have two or more different functions that call them, because
  411. they have two different calling conventions that cannot be easily captured
  412. using C's type system. These should be obvious from the name; failing
  413. that, the header file says exactly which SWI is called, and which values
  414. are placed into which registers. A few examples are described here, to
  415. give an idea of why variants exist.
  416.  
  417.    Colourtrans_select_table_for_sprite() (variant of
  418. colourtrans_select_- table()) takes an |osspriteop_area *| and an
  419. |osspriteop_id|, rather than an |os_mode| and an |os_palette *|, as its
  420. first two arguments. The same applies to
  421. colourtrans_generate_table_for_sprite() (variant of colourtrans_-
  422. generate_table()) and colourtrans_select_gcol_table_for_sprite() (variant of
  423. colourtrans_select_gcol_table()).
  424.  
  425.    Os_read_colour() (variant of os_set_colour()) is provided so that
  426. os_set_colour() can remain backwards-compatible.
  427.  
  428.    Squash_compress_return_sizes() (variant of squash_compress()) and
  429. squash_decompress_return_sizes() (variant of squash_decompress()) are
  430. provided because of the different purposes dependent on bit 3 of R0.
  431.  
  432.    Stringset{set,get}selected_string() and 
  433. stringset{set,get}selected_index() are both provided, to allow correct
  434. typechecking of the string or integer argument.
  435.  
  436.    Territory_read_symbols() is divided into 3 variants, territory_read_-
  437. boolean_symbols(), territory_read_integer_symbols() and territory_read_-
  438. string_symbols(), because different symbols have different types.
  439.  
  440.    Wimp_send_message_to_window() (variant of wimp_send_message()) takes
  441. a |wimp_w| and a |wimp_i| rather than a |wimp_t|, and returns a result
  442. (the task handle) which wimp_send_message() does not.
  443.  
  444. Conclusion
  445. ==========
  446.    Although there seem to be a lot of rules, that is because the RISC O S
  447. A P I is large. For normal application programming, most of it is not
  448. needed: applications don't normally deal with vectors, upcalls or service
  449. calls, for example, or do any direct access to disc structures. However,
  450. this is not ruled out. The C headers contain the complete description of
  451. exactly what each function does in terms of the mapping of the arguments to
  452. ARM registers, so no other documentation is needed.
  453.  
  454.    OSLib provides a very convenient interface to the RISC O S programmer,
  455. since all the facilities of the C compiler are available to catch errors
  456. and generate good code. It is conceptually very small, in that it is
  457. completely documented by this file. As a bonus, code written using it is
  458. smaller and faster than code written using other means.
  459.  
  460. Disclaimer
  461. ==========
  462.  
  463.    OSLib is copyright © 1995 Acorn Computers Ltd. It is distributed in
  464. the hope that it will be useful, but without any warranty; without even
  465. the implied warranty of merchantability or fitness for a particular
  466. purpose.
  467.  
  468.    Fault reports and suggestions for improvement may be sent to the
  469. author, Jonathan Coxhead <jcoxhead@acorn.co.uk>. Although this is an
  470. Acorn address, OSLib is not an official Acorn product.
  471.